package org.duang.event;

import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;

import org.duang.event.core.Event;
import org.duang.event.core.EventListener;
import org.duang.event.core.EventModel;
import org.duang.kit.MultiMaps;
import org.duang.kit.ThreadPoolKit;
import org.duang.kit.ToolsKit;

import ch.qos.logback.core.net.SyslogOutputStream;

@SuppressWarnings("rawtypes")
public class EventHandler {
	
	private final MultiMaps<Type, EventListener> map;
	private final ExecutorService pool;
//	private final static String DUANG_EVENT_KEY = "_duang-event-key_"; 
	private static ConcurrentHashMap<String, EventListener> eventListenerMap = new ConcurrentHashMap<String, EventListener>();
	
	public EventHandler(MultiMaps<Type, EventListener> map, ExecutorService pool) {
		super();
		this.map = map;
		this.pool = pool;
	}
	
	public void executeEvent(final Event event){
		EventListener listener = findEventListener(event);
		if(ToolsKit.isNotEmpty(listener)){
			 String key = listener.getKey();
			 if(ToolsKit.isEmpty(key)) throw new NullPointerException("listener key is null");
			 eventListenerMap.putIfAbsent(key, listener);
			 exceute(listener,event, false);		//默认为同步执行
		} else {
			throw new NullPointerException("listener is null");
		}
	}
	
//	@SuppressWarnings("unchecked")
//	public void executeEvent(final Event event, final String key){
//		List<EventListener> list = map.get(event.getClass());
//		for(Iterator<EventListener> it = list.iterator(); it.hasNext();){
//			final EventListener listener = it.next();
//			if( listener.getKey().equals(key) || DUANG_EVENT_KEY.equals(key)){
//				if(ToolsKit.isNotEmpty(pool)){
//					pool.execute(new Runnable(){
//						public void run() {
//							listener.onEvent(event);
//						}
//					});
//				} else {
//					listener.onEvent(event);
//				}
//				break;
//			}
//		}
//	}
	
	public <T> T executeEvent(final EventModel model){
		String key = model.getKey();
		EventListener listener = eventListenerMap.get(key);
		if(ToolsKit.isEmpty(listener)){
			listener = findEventListener(key);
			if(ToolsKit.isEmpty(listener)) throw new NullPointerException("listener is null");
			eventListenerMap.put(key, listener);
		}
		final Event event = new Event(model.getModel());
		return exceute(listener,event, model.isAync());
	}
	
	private EventListener findEventListener(Event event) {
		List<EventListener> list = map.get(event.getClass());
		return list.iterator().next();
	}
	
	private EventListener findEventListener(String key) {
		for(Iterator<Entry<Type, List<EventListener>>> it = map.entrySet().iterator(); it.hasNext();){
			Entry<Type, List<EventListener>> entry = it.next();
			 List<EventListener> eventListener = entry.getValue();
			 for(final EventListener listener : eventListener) {
				 if(listener.getKey().equals(key)){
					 return listener;
					}
			 }
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	private <T> T exceute(final EventListener listener, final Event event, final boolean aync) {
//		Type type = ((ParameterizedType) listener.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[1];
		if(aync){
			/* 执行任务的话也没用,也是要等待返回结果
			return (T)ThreadPoolKit.execute(new Callable(){
				public T call() throws Exception {
					Thread.currentThread().sleep(5000l);
					return  (T)listener.onEvent(event);
				}
			});
			*/
			ThreadPoolKit.execute(new Thread(){				
				public void run() {
					listener.onEvent(event);
				}
			});
			return (T)null;		//如果是异步的话，就直接返回null;
		} else {
			return (T)listener.onEvent(event);
		}
	}
}
